#include "stdafx.h"
#include "xParticleRenderPlug.h"

namespace XE	
{



	const  xString xParticleBillBoardRender::xParticleRenderType="BillBoardRender";


	xParticleBillBoardRender::xParticleBillBoardRender(const xString& name,xParticleTemplate* pParent)
		:xParticleRender(name,pParent)
	{
		m_pVertexDecl = xHardBufferManager::getSingleton().CreateVertexDeclaration();
		if(m_pVertexDecl==NULL)
		{
			xLogMessager::getSingleton().logMessage("Create xParticleBillBoardRender Fail,CreateVertexDeclaration Fail");
			throw("Create Particle System Fail,CreateVertexDeclaration Fail");
		}

		WORD offset = 0;
		m_pVertexDecl->AddVertexElement(0,offset,D3DDECLTYPE_FLOAT3,D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_POSITION,0);
		m_pVertexDecl->AddVertexElement(0,offset,D3DDECLTYPE_FLOAT2,D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_POSITION,1);
		m_pVertexDecl->AddVertexElement(0,offset,D3DDECLTYPE_D3DCOLOR,D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_COLOR,0);
		m_pVertexDecl->AddVertexElement(0,offset,D3DDECLTYPE_FLOAT2,D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_TEXCOORD,0);
		m_pVertexDecl->AddEndElement();



		m_pMaterial = xMaterialManager::getSingleton().GetByName("xParticleMaterial");
		if(m_pMaterial.isNull())
		{
			m_pMaterial = xMaterialManager::getSingleton().CreateResource("xParticleMaterial","particle.xmat");
		}



	}

	xParticleBillBoardRender::~xParticleBillBoardRender()
	{
		xHardBufferManager::getSingleton().DestoryVertexDeclaration(m_pVertexDecl);
	}


	HRESULT  xParticleBillBoardRender::
		Render(XRenderSystem* pRender,xParticleSystemInstance* pParticleSystem,const xCamera* pCamera)
	{
		size_t particleNumber = pParticleSystem->GetActiveParticleNumber();
		if(particleNumber==0)
			return X_OK;


		xVertexHardBuffer* pVertexHardBuffer = xHardBufferManager::getSingleton().RequestDynamicVertexHardBuffer(m_pVertexDecl->GetVertexSize(),particleNumber*4);
		if(pVertexHardBuffer==NULL)
		{
			xLogMessager::getSingleton().logMessage("Create Particle System Fail,Create DynamicVertex Buffer Fail");
			return X_FAIL;
		}

		xIndexHardBuffer* pIndexHardBuffer  = xHardBufferManager::getSingleton().RequestDynamicIndexHardBuffer(IndexHardBufferType_16,particleNumber*6);
		if(pIndexHardBuffer==NULL)
		{
			xLogMessager::getSingleton().logMessage("Create Particle System Fail,Create DynamicIndex Buffer Fail");
			return X_FAIL;
		}


		ParticleList::const_iterator it =  pParticleSystem->GetActiveParticeList().begin();
		ParticleList::const_iterator itend =  pParticleSystem->GetActiveParticeList().end();

		float* pVb = (float*)pVertexHardBuffer->Lock();
		if(pVb==NULL)
			return X_FAIL;
		for(;it!=itend;++it)
		{
			xParticle* pPar = (*it);

			//------position
			*pVb++=pPar->GetPosition().x;
			*pVb++=pPar->GetPosition().y;
			*pVb++=pPar->GetPosition().z;

			//--size
			*pVb++= - (pPar)->GetSize().x;
			*pVb++=(pPar)->GetSize().y;

			//-color
			DWORD* color = (DWORD*)pVb;
			*color = pPar->m_Color;
			pVb++;

			*pVb++ = 0.0f;
			*pVb++ = 0.0f;
			//--------------------------------------------------
			*pVb++=(pPar)->GetPosition().x;
			*pVb++=(pPar)->GetPosition().y;
			*pVb++=pPar->GetPosition().z;


			*pVb++= - (pPar)->GetSize().x;
			*pVb++=-(pPar)->GetSize().y;

			//-color
			color = (DWORD*)pVb;
			*color = pPar->m_Color;
			pVb++;

			*pVb++ = 0.0f;
			*pVb++ = 1.0f;
			//--------------------------------------------------
			//--------------------------------------------------
			*pVb++=(pPar)->GetPosition().x;
			*pVb++=(pPar)->GetPosition().y;
			*pVb++=(pPar)->GetPosition().z;

			*pVb++= (pPar)->GetSize().x;
			*pVb++=-(pPar)->GetSize().y;

			//-color
			color = (DWORD*)pVb;
			*color = pPar->m_Color;
			pVb++;

			*pVb++ = 1.0f;
			*pVb++ = 1.0f;

			//--------------------------------------------------
			*pVb++=(pPar)->GetPosition().x;
			*pVb++=(pPar)->GetPosition().y;
			*pVb++=(pPar)->GetPosition().z;

			*pVb++= (pPar)->GetSize().x;
			*pVb++=(pPar)->GetSize().y;

			//-color
			color = (DWORD*)pVb;
			*color = pPar->m_Color;
			pVb++;

			*pVb++ = 1.0f;
			*pVb++ = 0.0f;

		}

		pVertexHardBuffer->UnLock();
		int cc = sizeof(WORD);
		WORD* pIb = (WORD*)pIndexHardBuffer->Lock();
		if(pIb==NULL)
		{
			return X_FAIL;
		} 


		for(size_t j = 0;j<particleNumber;++j)
		{

			*pIb++=j*4+0;
			*pIb++=j*4+2;
			*pIb++=j*4+1;


			*pIb++=j*4+0;
			*pIb++=j*4+3;
			*pIb++=j*4+2;
		}

		pIndexHardBuffer->UnLock();




		if(FAILED(pRender->SetVertexBuffer(0,pVertexHardBuffer)))
			return X_FAIL;

		if(FAILED(pRender->SetVertexDeclaration(m_pVertexDecl)))
			return X_FAIL;

		if(FAILED(pRender->SetIndexBuffer(pIndexHardBuffer)))
			return X_FAIL;

		if(FAILED(pRender->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,0,particleNumber*4,0,particleNumber*2)))
			return X_FAIL;





	}



	void xParticleBillBoardRender::clone(const xParticleRender* pRender)
	{
		xParticleRender::clone(pRender);

	}



	const xString xParticleBillBoardRenderFactory::RenderType="BillBoardRender";



}